﻿using System;

namespace Lesson12_结构体
{
    #region 基本概念
    //结构体是一种自定义变量类型 类似枚举
    //它是数据和函数的集合
    //在结构体中 可以申明各种变量和方法

    //作用：用来表现存在关系的数据集合 比如用结构体表现学生 职员 等
    #endregion

    #region 基本语法
    //结构体一般写在 namespace 语句块中
    //结构体关键字 struct
    //成员：变量 函数(方法)

    //struct 自定义结构体名
    //{
    //    //第一部分
    //    //变量

    //    //第二部分
    //    //构造函数

    //    //第三部分
    //    //函数(可选)
    //}

    //结构体命名 使用帕斯卡命名法
    #endregion

    #region 实例
    struct Student
    {
        #region 访问修饰符
        //修饰结构体中变量和方法 表示被修饰成员是否能够被外部使用
        //public 公开的 表示该成员可以被任何代码访问
        //private 私有的 表示该成员只能在当前代码块中被访问
        //若不写访问修饰符 则默认该成员被 private 修饰
        #endregion

        //变量
        //结构体中申明的变量 不能初始化
        //变量可以是任何的类型 包括结构体 但不能是自身所在的结构体
        public int age;
        public bool sex;
        public int id;
        public string name;

        //结构函数
        #region 构造函数
        //用于方便在外部对结构体成员初始化
        //注意：
        // 1.没有返回值
        // 2.函数名必须与结构体名相同
        // 3.必须有参数
        // 4.申明一个构造函数 必须在其中对所有变量初始化 
        // 5.可以重载 但不管如何传参 都必须对所有成员变量进行初始化
        // 6.默认存在一个无参的构造函数 无论我们是否申明构造函数 该无参构造函数都存在，但我们不能主动申明无参构造函数
        public Student(int age, bool sex, int id, string name)
        {
            //使用this关键字 用于区别成员变量与传入的参数
            //this.进行初始化的成员变量 = 传入的参数
            this.age = age;
            this.sex = sex;
            this.id = id;
            this.name = name;
        }
        #endregion

        //函数(方法)
        //表示该结构体的行为
        //在结构体中的方法 目前不需要加static关键字
        public void Speak()
        {
            //内部成员可以直接使用
            //外部成员需传入参数
            Console.WriteLine("学生年龄{0}，性别{1}，学号{2}，姓名{3}", age, sex ? "男" : "女", id, name);
        }

    }
    #endregion

    class Program
    {
        static void Main(string[] args)
        {
            #region 结构体的使用
            //申明一个自定义结构体类型 的结构体变量
            Student stu1;
            //访问结构体成员并赋值
            stu1.name = "LiberTy";
            stu1.age = 19;
            #endregion

            #region 调用构造函数初始化
            //new 构造函数名(参数)
            Student stu2 = new Student(18, false, 10086, "LiberTy");
            stu2.Speak();
            //也可以调用默认构造函数 再单独初始化
            Student stu3 = new Student();
            stu3.age = 20;
            #endregion
        }
    }
}